package com.jzo2o.foundations.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.RegionMapper;
import com.jzo2o.foundations.mapper.ServeItemMapper;
import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.model.domain.ServeItem;
import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import com.jzo2o.foundations.service.ServeService;
import com.jzo2o.mysql.utils.PageHelperUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Yzxxn
 */
@Service
public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements ServeService {

    @Autowired
    private ServeMapper serveMapper;

    @Autowired
    private ServeItemMapper serveItemMapper;

    @Autowired
    private RegionMapper regionMapper;

    @Override
    public void offHot(Long id) {
        Serve serve = lambdaQuery().eq(Serve::getId, id).one();
        if (Objects.isNull(serve) || serve.getIsHot() == 0) {
            throw new ForbiddenOperationException("当前区域服务热点状态不支持修改！");
        }
        boolean update = lambdaUpdate()
                .eq(Serve::getId, id)
                .set(Serve::getIsHot, 0)
                .update();
        if (!update) {
            throw new ForbiddenOperationException("区域服务热点状态修改失败！");
        }
    }

    @Override
    public void onHot(Long id) {
        Serve serve = lambdaQuery().eq(Serve::getId, id).one();
        if (Objects.isNull(serve) || serve.getIsHot() == 1) {
            throw new ForbiddenOperationException("当前区域服务热点状态不支持修改！");
        }
        boolean update = lambdaUpdate()
                .eq(Serve::getId, id)
                .set(Serve::getIsHot, 1)
                .update();
        if (!update) {
            throw new ForbiddenOperationException("区域服务热点状态修改失败！");
        }
    }

    @Override
    public void deleteServe(Long id) {
        Serve serve = lambdaQuery().eq(Serve::getId, id).one();
        if (Objects.isNull(serve) || !(serve.getSaleStatus() == FoundationStatusEnum.INIT.getStatus())) {
            throw new ForbiddenOperationException("当前区域服务状态不支持删除！");
        }
        boolean remove = remove(Wrappers.<Serve>lambdaQuery().eq(Serve::getId, id));
        if (!remove) {
            throw new ForbiddenOperationException("区域服务删除失败！");
        }
    }

    @Override
    public PageResult<ServeResDTO> page(ServePageQueryReqDTO servePageQueryReqDTO) {
        return PageHelperUtils.selectPage(servePageQueryReqDTO,
                () -> baseMapper.queryServeListByRegionId(servePageQueryReqDTO.getRegionId()));
    }

    @Override
    @Transactional
    public void add(List<ServeUpsertReqDTO> serveUpsertReqDTO) {
        // 服务项id集合
        List<Long> serveItemIds = serveUpsertReqDTO.stream().map(ServeUpsertReqDTO::getServeItemId).collect(Collectors.toList());
        // 区域id集合
        Set<Long> regionIds = serveUpsertReqDTO.stream().map(ServeUpsertReqDTO::getRegionId).collect(Collectors.toSet());

        // 服务项对应集合
        //2.1、检验服务项是否为启用状态
        List<ServeItem> serveItemList = serveItemMapper.selectList(Wrappers.<ServeItem>lambdaQuery()
                .in(ServeItem::getId, serveItemIds)
                //TODO
                .eq(ServeItem::getActiveStatus, FoundationStatusEnum.ENABLE.getStatus())
        );
        if (serveItemList.size() != serveItemIds.size()) {
            throw new ForbiddenOperationException("该服务项未启用或不存在！");
        }

        // 区域对应集合
        //2.2、检验是否区域已有该服务
        Long count = lambdaQuery()
                .in(Serve::getRegionId, regionIds)
                .in(Serve::getServeItemId, serveItemIds)
                .count();
        if (count > 0) {
            throw new ForbiddenOperationException("该服务项不能重复添加！");
        }

        //2.3、检验该区域是否存在
        List<Region> regions = regionMapper.selectList(Wrappers.<Region>lambdaQuery()
                .in(Region::getId, regionIds));
        if (regions.size() != regionIds.size()) {
            throw new ForbiddenOperationException("该区域不存在！");
        }

        //3、新增服务
        serveUpsertReqDTO.forEach(st -> {
            Serve serve = BeanUtil.toBean(st, Serve.class);
            regions.forEach(region -> {
                if (Objects.equals(st.getRegionId(), region.getId())) {
                    serve.setCityCode(region.getCityCode());
                }
            });
            serveItemList.forEach(si -> {
                if (Objects.equals(st.getServeItemId(), si.getId())) {
                    serve.setPrice(si.getReferencePrice());
                }
            });
            serveMapper.insert(serve);
        });
    }

    @Override
    public void update(Long id, BigDecimal price) {
        boolean update = lambdaUpdate()
                .eq(Serve::getId, id)
                .set(Serve::getPrice, price)
                .update();
        if (!update) {
            throw new CommonException("区域服务价格修改失败");
        }
    }

    @Override
    public void onSale(Long id) {
        //区域服务当前状态为草稿或下架
        Serve serve = baseMapper.selectById(id);
        if (ObjUtil.isNull(serve) || serve.getSaleStatus() == FoundationStatusEnum.ENABLE.getStatus()) {
            throw new ForbiddenOperationException("当前服务状态不支持上架！");
        }

        //服务项是否启用
        ServeItem serveItem = serveItemMapper.selectOne(Wrappers.<ServeItem>lambdaQuery()
                .eq(ServeItem::getId, serve.getServeItemId()));
        if (!(serveItem.getActiveStatus() == FoundationStatusEnum.ENABLE.getStatus())) {
            throw new ForbiddenOperationException("当期服务项状态不支持上架");
        }

        //修改状态为上架
        boolean update = lambdaUpdate()
                .eq(Serve::getId, id)
                .set(Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus())
                .update();
        if (!update) {
            throw new ForbiddenOperationException("修改上架状态失败！");
        }
    }

    @Override
    public void offSale(Long id) {
        Serve serve = lambdaQuery().eq(Serve::getId, id).one();
        if (Objects.isNull(serve) || !(serve.getSaleStatus() == FoundationStatusEnum.ENABLE.getStatus())) {
            throw new ForbiddenOperationException("当前服务状态不支持下架！");
        }

        boolean update = lambdaUpdate()
                .eq(Serve::getId, id)
                .set(Serve::getSaleStatus, FoundationStatusEnum.DISABLE.getStatus())
                .update();
        if (!update) {
            throw new ForbiddenOperationException("修改下架状态失败！");
        }
    }
}
